package ru.hh.team02.chat.server;

import ru.hh.team02.chat.database.*;
import ru.hh.team02.chat.client.Client;
import ru.hh.team02.chat.client.ClientRegistry;
import ru.hh.team02.chat.database.DatabaseServiceInterface;
import ru.hh.team02.chat.logger.SimpleLogger;
import ru.hh.team02.chat.messaging.SendingService;
import ru.hh.team02.chat.utils.ThreadPerTaskExecutor;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {
    private static final int PORT = 2004;

    private static final ThreadPerTaskExecutor EXECUTOR = new ThreadPerTaskExecutor();

    // XXX [Oleg] Why do we need null here? They are already initialized to null when creating on the heap.
    private ServerSocket listener = null;

    /*
     * Listen to the port. On connection create a new Client object,
     * start a new thread and bind it to the Client object.
     */
    public void run() {
        try {
            listener = new ServerSocket(PORT);
            System.out.println("waiting for connection...");
            // XXX [MY] This statement cannot be completed by java way.
            // XXX [Oleg] I think this is OK, as our server is not intended to be terminated :)
            while (true) {
                try {
                    final Socket connection = listener.accept();
                    EXECUTOR.execute(new Client(connection));
                } catch (IOException e) {
                    // XXX [Oleg] Logger?
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            // XXX [Oleg] Logger?
            System.out.println("server went down");
            // XXX [Oleg] OMG! Logger?
            e.printStackTrace();
        } finally {
            try {
                if (listener != null) {
                    listener.close();
                }
            } catch (IOException e) {
                // XXX [Oleg] Logger?
                e.printStackTrace();
            }
        }
    }
}
